# coding: utf-8
# author: t_wolf


from initial import *
from utils import *
from check import *
from fr_filter import *
from web_utils import *
from drive import *

# 利用导入间隙根据配置生成RUL映射表

if CONFIGS.BASE.url_mode == "dynamic":
    regexp_pattern = re.compile(r"@frame_worker\(\s*mapping\s*=\s*(.+?)\s*\)[\s.]*class\s*(.+?)\(Base\):")
    TMP_MAP = map(
        lambda x: {
            os.path.splitext(x)[0]: re.findall(
                regexp_pattern,
                open(
                    os.path.join(CONFIGS.BASE.business_path, x)
                ).read()
            )
        },
        filter(
            lambda y: y not in ('base.py', '__init__.py'),
            [_file for _file in os.listdir(CONFIGS.BASE.business_path) if os.path.splitext(_file)[1] == '.py']
        )
    )

    MID_MAP = []
    for _dict in TMP_MAP:
        for _key, _values in _dict.items():
            [MID_MAP.append((_map[0], "%s.%s" % (_key, _map[1]))) for _map in _values]

    iter_numb = iter_factor(VARIABLES.LIMIT_ITER)
    URL_MAP = tuple(
        map(
            lambda z: z if iter_numb.next() % 2 == 0 else "%s.%s" % (CONFIGS.BASE.business_path, z),
            reduce(lambda x, y: list(x) + list(y), MID_MAP)
        )
    )
    del TMP_MAP, MID_MAP, iter_numb

elif CONFIGS.BASE.url_mode == "default":
    TMP_MAP = eval(CONFIGS.BASE.url_map) if len(CONFIGS.BASE.url_map) else DEFAULT_MAP
    for _map in TMP_MAP.keys():
        TMP_MAP[_map] = "%s.%s" % (CONFIGS.BASE.business_path, TMP_MAP[_map])
    URL_MAP = tuple(reduce(lambda x, y: list(x) + list(y), TMP_MAP.items()))
else:
    raise web.internalerror("Unknown Value for [url_mode]")


def _frame_variable_assign(method):
    """
    为每次请求注入活力
    :param method: 要注入的请求类型
    :return: 返回一个充满新鲜变量的请求对象
    """

    def variable_inject(self, request_pattern=None):
        inject_object_by_dict(
            self,
            {
                "header": web.ctx.env,
                "session": web.ctx.session,
                "request": REQUEST.DISPOSE_DATA[REQUEST.DataType.PARAM](),
                "pattern": request_pattern,
            }
        )
        logger.debug("current request[%s: %s]" % (self.header_get("REQUEST_METHOD"), self.header_get("PATH_INFO")))
        logger.debug(" Header: %s" % self.header)
        logger.debug("Session: %s" % self.session.items())
        logger.debug("Request: %s" % self.request.items())
        return eval("self.%s" % method)()

    return variable_inject


def frame_worker(url_origin="/"):
    """
    指定类为框架工厂类,必须在业务最顶层引入
    :param url_origin: 监听的url的原始正则表达式
    :return: 注入处理数据后的类
    """

    def class_wrapper(cls):
        inject_object_by_dict(
            cls,
            {
                "frame_worker": True,
                "pages": web.config.render,
                "url_origin": url_origin,
            }
        )

        for _method in REQUEST.Method.method_list:
            setattr(cls, _method.upper(), _frame_variable_assign(_method))

        return cls

    return class_wrapper


def reg_filter(filter_item, args_list, on_fail=None):
    """
    注册过滤器,插入对象前就是全局过滤,插入方法前就是局部过滤,只针对特定请求
    :param filter_item: 过滤方法
    :param args_list: 过滤方法的入参列表
    :param on_fail: 过滤失败如何处理
    :return: 过滤通过则接着往下走,否则返回异常
    """

    def inject_request(obj):
        if hasattr(obj, "func_doc"):
            def request_injector(self):
                return obj(self) if filter_item(self, args_list) else on_fail

            return request_injector
        else:
            obj.filter_list.append([filter_item, args_list, on_fail])
            return obj

    return inject_request


def reg_handler():
    pass
